package com.mtons.mblog.modules.service.impl;

import com.mtons.mblog.modules.entity.DocumentQuestion;
import com.mtons.mblog.modules.repository.DocumentQuestionRepository;
import com.mtons.mblog.modules.service.DocumentQuestionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;
import org.hibernate.search.jpa.FullTextEntityManager;
import org.hibernate.search.jpa.FullTextQuery;
import org.hibernate.search.jpa.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DocumentQuestionServiceImpl implements DocumentQuestionService {

    @Autowired
    private EntityManager entityManager;

    @Autowired
    private DocumentQuestionRepository documentQuestionRepository;

    @Override
    public Page<DocumentQuestion> search(Pageable pageable, String term) throws Exception {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        QueryBuilder builder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(DocumentQuestion.class).get();

        Query luceneQuery = builder
                .keyword()
                .fuzzy()
                .withEditDistanceUpTo(1)
                .withPrefixLength(1)
                .onFields("title", "content")
                .matching(term).createQuery();

        FullTextQuery query = fullTextEntityManager.createFullTextQuery(luceneQuery, DocumentQuestion.class);
        query.setFirstResult(0);
        query.setMaxResults(5);

        SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span style='color:red;'>", "</span>");
        QueryScorer scorer = new QueryScorer(luceneQuery);
        Highlighter highlighter = new Highlighter(formatter, scorer);

        List<DocumentQuestion> list = query.getResultList();
        List<DocumentQuestion> rets = list.stream().map(po -> {
            try {
                // 处理高亮
                String title = highlighter.getBestFragment(analyzer, "title", po.getTitle());
                String content = highlighter.getBestFragment(analyzer, "content", po.getContent());
                if (StringUtils.isNotEmpty(title)) {
                    po.setTitle(title);
                }
                if (StringUtils.isNotEmpty(content)) {
                    po.setContent(po.getContent());
                }
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
            return po;
        }).collect(Collectors.toList());
        return new PageImpl<>(rets, pageable, query.getResultSize());
    }

    @Override
    public void resetIndexes() {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        fullTextEntityManager.createIndexer(DocumentQuestion.class).start();
    }

    @Transactional
    @Override
    public long add(DocumentQuestion documentQuestion) {
        documentQuestion.setCreated(new Date());
        documentQuestionRepository.save(documentQuestion);
        return 0;
    }
}
